﻿//-----------------------------------------------------------------------
// <copyright file="SA1202.cs" company="AXA">
//     Copyright (c) AXA. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace c0x3y.StyleCopFixer.Errors
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using EnvDTE;
    using EnvDTE80;
    using System.Diagnostics;
using System.Globalization;

    public class SA1202
    {
        private List<CodeElement> elementsList = new List<CodeElement>();
        private List<EnvDTE.CodeFunction> functions = new List<CodeFunction>();

        
        public void Run(EnvDTE.DTE environment, ErrorItem selectedError)
        {
            selectedError.Navigate();
            this.UpdateCode(vsCMAccess.vsCMAccessPrivate, new vsCMAccess[] { vsCMAccess.vsCMAccessPublic, vsCMAccess.vsCMAccessProject, vsCMAccess.vsCMAccessProjectOrProtected, vsCMAccess.vsCMAccessProtected }, environment);
            this.UpdateCode(vsCMAccess.vsCMAccessProtected, new vsCMAccess[] { vsCMAccess.vsCMAccessPublic, vsCMAccess.vsCMAccessProject, vsCMAccess.vsCMAccessProjectOrProtected}, environment);
            this.UpdateCode(vsCMAccess.vsCMAccessProjectOrProtected, new vsCMAccess[] { vsCMAccess.vsCMAccessPublic, vsCMAccess.vsCMAccessProject}, environment);
            this.UpdateCode(vsCMAccess.vsCMAccessProject, new vsCMAccess[] { vsCMAccess.vsCMAccessPublic}, environment);
        }

        private void UpdateCode(EnvDTE.vsCMAccess accessToFix, EnvDTE.vsCMAccess[] procceedingAccessTypes, DTE environment)
        {
            this.BuildMethods(environment);
            int lastFunction = 0;
            foreach (vsCMAccess item in procceedingAccessTypes)
            {
                int methodPosition = this.functions.FindLastIndex(function => function.Access == item);
                if (methodPosition > -1)
                {
                    lastFunction = methodPosition;
                }
            }
            
            for (int i = 0; i < lastFunction; i++)
            {
                if (this.functions[i].Access == accessToFix)
                {
                    
                    // Cut the method into memory
                    EditPoint startEditPoint = this.functions[i].StartPoint.CreateEditPoint();
                    EditPoint endEditPoint = this.functions[i].EndPoint.CreateEditPoint();
                    while (true)
                    {
                        string lineAbovetext = startEditPoint.GetLines(startEditPoint.Line - 1, startEditPoint.Line).Trim();
                        if (lineAbovetext.StartsWith("//") || lineAbovetext.StartsWith("["))
                        {
                            startEditPoint.LineUp();
                        }
                        else
                        {
                            break;
                        }
                    }

                    startEditPoint.Cut(endEditPoint);

                    EditPoint2 pasteEditPoint = (EditPoint2)this.functions[lastFunction].EndPoint.CreateEditPoint();
                    pasteEditPoint.InsertNewLine(2);
                    pasteEditPoint.Indent(null, this.functions[lastFunction].StartPoint.DisplayColumn / 4);
                    pasteEditPoint.Paste();
                }
            }
        }

        private void BuildMethods(DTE environment)
        {
            this.functions.Clear();
            TextSelection selection = (TextSelection)environment.ActiveDocument.Selection;
            CodeClass currentClass = (CodeClass)selection.ActivePoint.get_CodeElement(vsCMElement.vsCMElementClass);
            foreach (CodeElement item in currentClass.Members)
            {
                switch (item.Kind)
                {
                    case vsCMElement.vsCMElementFunction:
                        this.functions.Add((CodeFunction)item);
                        break;
                }
            }
        }
    }
}
